package cn.net.xyan.pay.wechat.controller

import cn.net.xyan.kotlin.StatusAndMessageError
import cn.net.xyan.kotlin.logger
import cn.net.xyan.pay.core.utils.RequestUtils
import cn.net.xyan.pay.wechat.WeChatConfiguration
import cn.net.xyan.pay.wechat.service.WeChatMenuService
import me.chanjar.weixin.mp.api.WxMpConfigStorage
import me.chanjar.weixin.mp.api.WxMpService
import org.springframework.beans.factory.InitializingBean
import org.springframework.stereotype.Controller
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage
import me.chanjar.weixin.mp.api.WxMpMessageHandler
import me.chanjar.weixin.mp.api.WxMpMessageRouter
import org.apache.commons.lang3.StringUtils
import org.springframework.beans.factory.annotation.Autowired

import org.springframework.http.HttpHeaders
import org.springframework.http.MediaType
import org.springframework.web.bind.annotation.*
import javax.servlet.http.HttpServletResponse
import org.springframework.web.bind.annotation.RequestMethod
import org.springframework.web.bind.annotation.RequestMapping
import java.net.URLEncoder
import javax.servlet.http.HttpServletRequest


/**
 * Created by zarra on 2017/3/28.
 */

@Controller
@RequestMapping("/weChat")
class MpController : InitializingBean {

    @Autowired
    lateinit var wxMpService: WxMpService

    @Autowired
    lateinit var wxMpConfigStorage: WxMpConfigStorage

    lateinit var wxMpMessageRouter: WxMpMessageRouter

    override fun afterPropertiesSet() {

        val handler = WxMpMessageHandler { wxMessage, context, wxMpService, sessionManager ->
            val m = WxMpXmlOutMessage.TEXT().content("测试加密消息").fromUser(wxMessage!!.toUser)
                    .toUser(wxMessage!!.fromUser).build()
            m
        }

        wxMpMessageRouter = WxMpMessageRouter(wxMpService)
        wxMpMessageRouter
                .rule()
                .async(false)
                //.content("哈哈") // 拦截内容为“哈哈”的消息
                .handler(handler)
                .end()



    }

    @ResponseBody
    @GetMapping(produces = arrayOf("text/plain;charset=utf-8"))
    fun authGet(@RequestParam(name = "signature", required = false) signature: String?
                , @RequestParam(name = "nonce", required = false) nonce: String?
                , @RequestParam(name = "timestamp", required = false) timestamp: String?
                , @RequestParam(name = "echostr", required = false) echoStr: String?): String? {
        if (StringUtils.isAnyBlank(signature, timestamp, nonce, echoStr)) {
            throw StatusAndMessageError(-1, "请求参数不正确")
        }

        if (wxMpService.checkSignature(timestamp, nonce, signature)) {
            return echoStr
        } else {
            throw StatusAndMessageError(-1, "验证签名出错")
        }
    }

    @ResponseBody
    @PostMapping(produces = arrayOf("application/xml; charset=UTF-8"))
    fun message(@RequestBody requestBody: String
                , @RequestParam("signature") signature: String
                , @RequestParam(name = "encrypt_type", required = false) encType: String?
                , @RequestParam(name = "msg_signature", required = false) msgSignature: String?
                , @RequestParam("timestamp") timestamp: String
                , @RequestParam("nonce") nonce: String): String? {

        logger.info("new message")

        if (!wxMpService.checkSignature(timestamp, nonce, signature)) {
            throw StatusAndMessageError(-1, "签名不正确")
        }

        val headers = HttpHeaders()

        headers.contentType = MediaType.parseMediaType("text/html;charset=utf-8")

        val realEncryptType = if (StringUtils.isBlank(encType)) "raw" else encType

        var inMessage: WxMpXmlMessage?
        var output: String? = null

        when (realEncryptType) {
            "raw" -> {
                inMessage = WxMpXmlMessage.fromXml(requestBody)
                val outMessage = wxMpMessageRouter.route(inMessage)
                output = outMessage.toXml()
            }

            "aes" -> {

                inMessage = WxMpXmlMessage.fromEncryptedXml(requestBody, wxMpConfigStorage, timestamp, nonce, msgSignature)
                val outMessage = wxMpMessageRouter.route(inMessage)
                outMessage.toEncryptedXml(wxMpConfigStorage)
            }

            else -> {
                throw StatusAndMessageError(-1, "未知的签名方法")
            }
        }

        return output
    }

    @RequestMapping(value = "/redirect/{page}", method = arrayOf(RequestMethod.GET))
    fun weixinRedirect(@PathVariable("page")page:String,httpServletResponse: HttpServletResponse) {
        var url = RequestUtils.absoluteURL("/page/$page?vendor=weChat")
        url = wxMpService.oauth2buildAuthorizationUrl(url,"snsapi_base","1")
        logger.info("redirect:$url")

        httpServletResponse.sendRedirect(url)
         //"redirect:$url"
    }

}